

class FormField < Widget
  attr_accessor :form

  def name
    @name
  end

  def name= name
    @name = name
  end

  def value
    raise 'implement me'
  end

  def dump
    value
  end

  def fill data
    self.value = data
    self
  end

  def recieve data
    self.value = data
    self
  end

  def submit
    dump
  end

  def has_value?
    raise "Not implemented in #{self.class}."
  end

  def link url
    form.page.link url
  end

  def visible?
    true
  end

  def to_s
    orig_name  = self.name

    names = []
    field = self

    while field!= nil
      if field.respond_to?(:name) && field.name
        names << field.name
      end
      field = field.parent
    end

    names.reverse!
    if names.length > 1
      if element.tag_name != 'div'
        element.name = names.shift + '['+names.join('][')+']'
      end
    end
    r = super
    self.name = orig_name
    r
  end




  class Test < FwTest
    def test_visible_by_default
      assert FormField.new.visible?
    end

    def test_has_value_raises_not_implemented
      assert_raise(RuntimeError) {FormField.new.has_value?}
    end
  end

end

class TextArea < FormField

  def name
    element.name
  end

  def name= name
    element.name= name
  end

  def initialize content, args = nil
    if args == nil
      e = Element.new('textarea', content)
    else
      e = Element.new('textarea', content, args)
    end
    init_element e
  end

  def value
    element.children.join('')
  end

  def value= v
    element.children = [v]
  end

  def has_value?
    true
  end
end


class Select < FormField
  def initialize args = {}, options = {}
    init_element el(:select, args)
    self.options = options
  end

  def name
    element.name
  end

  def name= name
    element.name= name
  end

  def options= o
    element.options = o
    self
  end

  def value
    #@value
    element.value
  end

  def value= v
    element.value = v
    #element.recieve(element.name => v)
    #@value = v
  end

  def has_value?
    true
  end

  def to_s
    self.element.children.each { |ch|
      if ch.value == @value.to_s
        ch.selected = 'selected'
      end
    }
    super
  end


  class SelectTest < FwTest

    def test_value_is_nil_from_the_start
      b = Select.new
      assert_equal nil, b.value
    end

    def test_select_tag
      s = Select.new :name => 'abc'
      assert_match(/<select name="abc" class="Select"><\/select>/, s.to_s)
    end

    def test_add_option
      s = Select.new
      s.options = [['id', 'label']]
      assert_match(/<option value="id">label<\/option>/, s.to_s)
    end

    def test_option_with_right_values_gets_selected
      s = Select.new
      s.options = [['1', 'green']]
      s.value = '1'
      assert_match(/<option value="1" selected="selected">green<\/option>/, s.to_s)
    end
  end
end




class Input < FormField
  def name
    element.name
  end

  def name= name
    element.name= name
  end

  def initialize args = {}
    init_element Element.new('input',{ :type => 'text'}.merge(args))
  end

  def value
    element.value
  end

  def value= v
    element.value = v
  end

  def has_value?
    true
  end

  def visible?
    true
  end
end

class InputText < Input
  def initialize args = {}
    super({:type => 'text'}.merge(args))
  end

  class Test < FwTest

    def test_initial_dump_is_nil
      assert_equal(nil, InputText.new(:name => 'name').dump)
    end

    def test_fill
      assert_equal('blue', InputText.new(:name => 'color').fill('blue').dump)
    end

    def test_recieve
      assert_equal('blue', InputText.new(:name => 'color').recieve('blue').dump)
    end

    def test_recieve_submit
      assert_equal('blue', InputText.new(:name => 'color').recieve('blue').submit)
    end
  end
end



class CheckBox < Input
  def initialize label, args = {}
    @label = label
    super({:type => 'checkbox', :value => 'yes'}.merge(args))
  end

  def value= v
    if (v == 'yes') || (v === true)
      element.checked = 'checked'
      @value = true
    else
      element.checked = nil
      @value = false
    end
  end

  def value
    @value
  end

  def to_s
    element.id
    super + Element.new(
      :label,
      @label,
      :for => element.id
    ).to_s
  end

  class Test < FwTest

    def test_initial_dump_is_nil
      assert_equal(nil, InputText.new(:name => 'name').dump)
    end

    def test_fill
      assert_equal('blue', InputText.new(:name => 'color').fill('blue').dump)
    end

    def test_recieve
      assert_equal('blue', InputText.new(:name => 'color').recieve('blue').dump)
    end

    def test_recieve_submit
      assert_equal('blue', InputText.new(:name => 'color').recieve('blue').submit)
    end
  end
end


class InputPassword < Input
  def initialize args = {}
    super({:type => 'password'}.merge(args))
  end
end


class InputInteger < Input
  def value
    super.to_i
  end
end

class InputHidden < Input
  def initialize args = {}
    super({:type => 'hidden'}.merge(args))
  end

  def visible?
    false
  end
end

class SubmitButton < Input
  def initialize args = {}
    super({:type => 'submit'}.merge(args))
    @pushed = false
  end

  def has_value?
    false
  end

  def recieve v
    @pushed = !!v
  end

  def pushed?
    @pushed
  end


  class Test < FwTest

    def test_does_not_have_value
      assert !SubmitButton.new.has_value?
    end

    def test_initially_not_pushed
      b = SubmitButton.new(:name => 'delete')
      assert !b.pushed?
    end

    def test_pushed_returns_true_when_recieved_value
      b = SubmitButton.new(:name => 'delete')
      b.recieve('whatever the value')
      assert b.pushed?
    end

    def test_pushed_returns_false_when_recieved_nil
      b = SubmitButton.new(:name => 'delete')
      b.recieve(nil)
      assert !b.pushed?
    end
  end
end
  

def triangle iterations
  rows = []
  @iterations = iterations
  iterations.times { |r|
    new_row = [1]
    if r >= 1
      row = rows[r-1]
      (r-1).times { |i|
        new_row << row[i]+row[i+1]
      }
      new_row << 1
    end
    rows << new_row
  }
  @numbers = rows
end








